//
//  UIView+Extension.m
//  TableDemo
//
//  Created by jutuo on 2020/3/28.
//  Copyright © 2020 jutuo. All rights reserved.
//

#import "UIView+Extension.h"
#import <objc/runtime.h>

@implementation UIView (Extension)
- (void)setX:(CGFloat)x
{
    CGRect frame = self.frame;
    frame.origin.x = x;
    self.frame = frame;
}

- (void)setY:(CGFloat)y
{
    CGRect frame = self.frame;
    frame.origin.y = y;
    self.frame = frame;
}

- (CGFloat)x
{
    return self.frame.origin.x;
}

- (CGFloat)y
{
    return self.frame.origin.y;
}

- (void)setCenterX:(CGFloat)centerX
{
    CGPoint center = self.center;
    center.x = centerX;
    self.center = center;
}

- (CGFloat)centerX
{
    return self.center.x;
}

- (void)setCenterY:(CGFloat)centerY
{
    CGPoint center = self.center;
    center.y = centerY;
    self.center = center;
}

- (CGFloat)centerY
{
    return self.center.y;
}

- (void)setWidth:(CGFloat)width
{
    CGRect frame = self.frame;
    frame.size.width = width;
    self.frame = frame;
}

- (void)setHeight:(CGFloat)height
{
    CGRect frame = self.frame;
    frame.size.height = height;
    self.frame = frame;
}

- (CGFloat)height
{
    return self.frame.size.height;
}

- (CGFloat)width
{
    return self.frame.size.width;
}

- (void)setSize:(CGSize)size
{
    CGRect frame = self.frame;
    frame.size = size;
    self.frame = frame;
}

- (CGSize)size
{
    return self.frame.size;
}

- (void)setOrigin:(CGPoint)origin
{
    CGRect frame = self.frame;
    frame.origin = origin;
    self.frame = frame;
}

- (CGPoint)origin
{
    return self.frame.origin;
}

- (CGFloat) top
{
    return self.frame.origin.y;
}

- (void) setTop: (CGFloat) newtop
{
    CGRect newframe = self.frame;
    newframe.origin.y = newtop;
    self.frame = newframe;
}

- (CGFloat) left
{
    return self.frame.origin.x;
}

- (void) setLeft: (CGFloat) newleft
{
    CGRect newframe = self.frame;
    newframe.origin.x = newleft;
    self.frame = newframe;
}

- (CGFloat) bottom
{
    return self.frame.origin.y + self.frame.size.height;
}

- (void) setBottom: (CGFloat) newbottom
{
    CGRect newframe = self.frame;
    newframe.origin.y = newbottom - self.frame.size.height;
    self.frame = newframe;
}

- (CGFloat) right
{
    return self.frame.origin.x + self.frame.size.width;
}

- (void) setRight: (CGFloat) newright
{
    CGFloat delta = newright - (self.frame.origin.x + self.frame.size.width);
    CGRect newframe = self.frame;
    newframe.origin.x += delta ;
    self.frame = newframe;
}

- (CGPoint)bottomLeft
{
    return CGPointMake(CGRectGetMinX(self.frame), CGRectGetMaxY(self.frame));
}

- (CGPoint)bottomRight
{
    return CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMaxY(self.frame));
}

- (CGPoint)topRight
{
    return CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMinY(self.frame));
}

- (void)removeAllSubviews
{
    while ([self.subviews count] > 0) {
        UIView *subview = [self.subviews objectAtIndex:0];
        [subview removeFromSuperview];
    }
}

- (void)removeViewWithTag:(NSInteger)tag
{
    if (tag == 0) {
        return;
    }
    UIView *view = [self viewWithTag:tag];
    if (view) {
        [view removeFromSuperview];
    }
}

- (void)removeSubViewArray:(NSMutableArray *)views
{
    for (UIView *sub in views) {
        [sub removeFromSuperview];
    }
}

- (void)removeViewWithTags:(NSArray *)tagArray
{
    for (NSNumber *num in tagArray) {
        [self removeViewWithTag:[num integerValue]];
    }
}

- (void)removeViewWithTagLessThan:(NSInteger)tag
{
    for (UIView *view in self.subviews) {
        if (view.tag > 0 && view.tag < tag) {
            [view removeFromSuperview];
        }
    }
  
}

- (void)removeViewWithTagGreaterThan:(NSInteger)tag
{
   
    for (UIView *view in self.subviews) {
        if (view.tag > 0 && view.tag > tag) {
            [view removeFromSuperview];
        }
    }
  
}


- (UIViewController *)controller
{
    for (UIView* next = [self superview]; next; next = next.superview) {
        UIResponder* nextResponder = [next nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController*)nextResponder;
        }
    }
    return nil;
}




- (void)shadowRadius:(CGFloat)shadowRadius shadowOffset:(CGSize)shadowOffset
{
    [self shadowRadius:shadowRadius shadowOffset:shadowOffset shadowOpacity:1 shadowColor:[UIColor blackColor]];
}
- (void)shadowRadius:(CGFloat)shadowRadius shadowOffset:(CGSize)shadowOffset shadowOpacity:(float)shadowOpacity shadowColor:(UIColor *)shadowColor
{
    self.layer.masksToBounds = NO;
    self.layer.shadowOffset = shadowOffset;
    self.layer.shadowRadius = shadowRadius;
    self.layer.shadowOpacity = shadowOpacity;
    self.layer.shadowColor = shadowColor.CGColor;
    self.layer.shadowPath =  [UIBezierPath bezierPathWithRect:self.layer.bounds].CGPath;
}


/**
 *  添加圆角和边的宽度
 */
- (void)cornerRadius:(CGFloat)cornerRadius masksToBounds:(BOOL)masksToBounds
{
    self.layer.cornerRadius = cornerRadius;
    self.layer.masksToBounds = masksToBounds;
}

/**
 *  添加边的宽度
 */
- (void)borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth
{
    self.layer.borderWidth = borderWidth;
    self.layer.borderColor = borderColor.CGColor;
}
- (void)cornerRadius:(CGFloat)radius
{
    [self cornerRadius:radius borderWidth:0 borderColor:nil];
}
- (void)cornerRadius:(CGFloat)radius
borderWidth:(CGFloat)borderWidth
         borderColor:(UIColor *_Nullable)borderColor
{
    [self cornerRadius:radius corners:UIRectCornerAllCorners borderWidth:borderWidth borderColor:borderColor borderLineJoin:kCGLineJoinRound layerName:@"maskLayer"];
}

- (void)cornerRadius:(CGFloat)radius corners:(UIRectCorner)corners
{
    [self cornerRadius:radius corners:UIRectCornerAllCorners borderWidth:0 borderColor:nil borderLineJoin:kCGLineJoinRound layerName:@"maskLayer"];
}
- (void)cornerRadius:(CGFloat)radius
    corners:(UIRectCorner)corners
borderWidth:(CGFloat)borderWidth
borderColor:(UIColor *_Nullable)borderColor
                    borderLineJoin:(CGLineJoin)borderLineJoin layerName:(NSString * _Nullable)name
{
    CAShapeLayer *maskLayer = nil;
    if ([self.layer.mask.name isEqualToString:name]) {
        maskLayer = self.layer.mask;
    }else{
        maskLayer = [CAShapeLayer layer];
    }
    UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, borderWidth)];
    
    maskLayer.frame = self.bounds;
    maskLayer.path = path.CGPath;
    self.layer.mask = maskLayer;
    maskLayer.shouldRasterize = YES;
    maskLayer.rasterizationScale = [UIScreen mainScreen].scale;
    
   //设置边框及填充色
    __block CAShapeLayer *borderLayer = nil;
    if (name.length) {
        NSArray<CALayer *> *subLayers = self.layer.sublayers;
        [subLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if([obj.name isEqualToString:name]){
                borderLayer = (CAShapeLayer *)obj;
                *stop = YES;
            }
        }];
    }
    
    if (!borderLayer) {
        borderLayer=[CAShapeLayer layer];
        borderLayer.name = name;
        [self.layer addSublayer:borderLayer];
    }
    
    borderLayer.path=path.CGPath;
    borderLayer.fillColor = [UIColor clearColor].CGColor;
    if (borderColor) {
        borderLayer.strokeColor = borderColor.CGColor;
    }
    
    if (borderWidth > 0) {
        borderLayer.lineWidth = borderWidth;
    }
    borderLayer.frame = self.bounds;
}

- (void)cornerRadiusWithtopLeft:(CGFloat)topLeftRadius bottomLeft:(CGFloat)bottomLeftRadius topRight:(CGFloat)topRightRadius bottomRight:(CGFloat)bottomRightRadius
{
    CGFloat width = self.bounds.size.width;
    CGFloat height = self.bounds.size.height;
    
    UIBezierPath *maskPath = [[UIBezierPath alloc]init];
    [maskPath moveToPoint:CGPointMake(topLeftRadius, 0)];
    [maskPath addLineToPoint:CGPointMake(width - topRightRadius, 0)];
    [maskPath addArcWithCenter:CGPointMake(width - topRightRadius, topRightRadius) radius:topRightRadius startAngle:  3 * M_PI / 2.0   endAngle: 0 clockwise:YES];
    
    [maskPath addLineToPoint:CGPointMake(width, height - bottomRightRadius)];
    [maskPath addArcWithCenter:CGPointMake(width - bottomRightRadius, height - bottomRightRadius) radius:bottomRightRadius startAngle:0 endAngle: M_PI / 2.0  clockwise:YES];
    [maskPath addLineToPoint:CGPointMake(bottomLeftRadius, height)];
    [maskPath addArcWithCenter:CGPointMake(bottomLeftRadius, height - bottomLeftRadius) radius:bottomLeftRadius startAngle: M_PI / 2.0 endAngle:M_PI clockwise:YES];
    [maskPath addLineToPoint:CGPointMake(0, topLeftRadius)];
    [maskPath addArcWithCenter:CGPointMake(topLeftRadius, topLeftRadius) radius:topLeftRadius startAngle:M_PI endAngle:3 * M_PI / 2.0  clockwise:YES];
    
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;
    
    maskLayer.shouldRasterize = YES;
    maskLayer.rasterizationScale = [UIScreen mainScreen].scale;
}

/**
 绘制虚线 -----
 * @paramer lineWidth: 线粗细
 * @paramer lineLength ： 线长
 * @paramer lineSpacing : 间隔
 * @paramer lineColor : 线的颜色
 */

- (void)drawDashLineWithlineWidth:(CGFloat)lineWidth lineLength:(CGFloat)lineLength lineSpacing:(CGFloat)lineSpacing lineColor:(UIColor *)lineColor
{
    CAShapeLayer *dashLine = [CAShapeLayer drawDashLine:self.bounds lineWidth:lineWidth lineLength:lineLength lineSpacing:lineSpacing lineColor:lineColor];
    [self.layer addSublayer:dashLine];
}

/**
 绘制虚线框  ----
          |    |
           ----

 * @paramer lineWidth: 线粗细
 * @paramer lineLength ： 线长
 * @paramer lineSpacing : 间隔
 * @paramer lineColor : 线的颜色
 */
- (void)drawDashLineBoxWithlineWidth:(CGFloat)lineWidth lineLength:(CGFloat)lineLength lineSpacing:(CGFloat)lineSpacing lineColor:(UIColor *)lineColor
{
    CAShapeLayer *dashLineBox = [CAShapeLayer drawDashLineBox:self.bounds lineWidth:lineWidth lineLength:lineLength lineSpacing:lineSpacing lineColor:lineColor];
    [self.layer addSublayer:dashLineBox];
}
@end



@implementation UIView (GestureRecognizer)

- (void)setGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer;
{
    for (UIGestureRecognizer *sender in self.gestureRecognizers) {
        if ([sender isKindOfClass:[gestureRecognizer class]]) {
            [self removeGestureRecognizer:sender];
        }
    }
    [self addGestureRecognizer:gestureRecognizer];
}

const void * tapGestureHandle = "tapGestureBlock";
- (void)addTapGesture:(void(^)(UITapGestureRecognizer *tap))handle
{
    if (!self.userInteractionEnabled) {
        self.userInteractionEnabled = YES;
    }
    UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
    [self addGestureRecognizer:tapGes];
    objc_setAssociatedObject(self, tapGestureHandle, handle, OBJC_ASSOCIATION_COPY);
}

BOOL doubleTap = NO;
- (void)tapAction:(UITapGestureRecognizer *)tapGesture {
    
    
    if (tapGesture.numberOfTapsRequired == 1) {
        if (doubleTap) {
            doubleTap = NO;
            return ;
        }
        void (^handle)(UITapGestureRecognizer *) = objc_getAssociatedObject(self, tapGestureHandle);
        handle(tapGesture);
        
    } else if (tapGesture.numberOfTapsRequired == 2) {
        doubleTap = YES;
        void (^handle)(UITapGestureRecognizer *) = objc_getAssociatedObject(self, doubleTapGestureHandle);
        handle(tapGesture);
    }
    
}

const void * doubleTapGestureHandle = "doubleTapGestureHandle";

- (void)addDoubleTapGesture:(void(^)(void))handle {
    if (!self.userInteractionEnabled) {
        self.userInteractionEnabled = YES;
    }
    UITapGestureRecognizer *doubleTapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
    doubleTapGes.numberOfTapsRequired = 2;
    [self addGestureRecognizer:doubleTapGes];
    objc_setAssociatedObject(self, doubleTapGestureHandle, handle, OBJC_ASSOCIATION_COPY);
}


@end

@implementation UIView (Reusable)
const NSString *reuseableKey = @"reuseableKey";
- (void)setReuseableViewInfo:(NSMutableDictionary *)reuseableViewInfo
{
    objc_setAssociatedObject(self, &reuseableKey, reuseableViewInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSMutableDictionary *)reuseableViewInfo
{
    NSMutableDictionary *reuseableViewInfo = objc_getAssociatedObject(self, &reuseableKey);
    if (!reuseableViewInfo) {
        reuseableViewInfo = [[NSMutableDictionary alloc]init];
        objc_setAssociatedObject(self, &reuseableKey, reuseableViewInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return reuseableViewInfo;
}

- (void)setReuseIdentifier:(NSString *)reuseIdentifier
{
    objc_setAssociatedObject(self, @selector(reuseIdentifier), reuseIdentifier, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSString *)reuseIdentifier
{
    return objc_getAssociatedObject(self, _cmd);
}


- (UIView *)dequeueReusableViewWithIdentifier:(NSString *)identifier
{
    UIView *reuseView = nil;
    UIViewReusableModel *reuseModel = self.reuseableViewInfo[identifier];
    
    if (!reuseModel) {
        reuseModel = [[UIViewReusableModel alloc]init];
        reuseModel.reuseIndex = -1;
        [self.reuseableViewInfo setValue:reuseModel forKey:identifier];
    }else{
        if (reuseModel.reusableViews.count > 0) {
            reuseView = reuseModel.reusableViews[reuseModel.reuseIndex];
            reuseModel.reuseIndex++;
        }
    }
    return reuseView;
}

//添加到重用池
- (void)addViewToReuseQueue:(UIView *)view
{
    [self addSubview:view];
    UIViewReusableModel *reuseModel = self.reuseableViewInfo[view.reuseIdentifier];
    if (!reuseModel) {
        reuseModel = [[UIViewReusableModel alloc]init];
        reuseModel.reuseIndex = -1;
        [self.reuseableViewInfo setValue:reuseModel forKey:view.reuseIdentifier];
    }
    NSMutableArray<UIView *> *reusableViews = reuseModel.reusableViews;
    [reusableViews addObject:view];
    reuseModel.reuseIndex++;
}

//移除多余的视图
- (void)removeRedundantViewFromReuseQueue
{
    NSArray *allReuseModels = [self.reuseableViewInfo allValues];
   
    for (UIViewReusableModel *reuseModel in allReuseModels) {
         NSMutableArray<UIView *> *reusableViews = reuseModel.reusableViews;
        while (reuseModel.reuseIndex < reusableViews.count - 1) {
            NSInteger next = reuseModel.reuseIndex + 1;
            UIView *view = reusableViews[next];
            [view removeFromSuperview];
            [reusableViews removeObjectAtIndex:next];
        }
        
        reuseModel.reuseIndex = (reusableViews.count == 0) ? -1 : 0;
    }
}

@end


@implementation UIViewReusableModel

- (NSMutableArray *)reusableViews
{
    if (!_reusableViews) {
        _reusableViews = [NSMutableArray array];
    }
    return _reusableViews;
}

@end
